package top.wshape1.shiziapi.message.listener;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.rabbitmq.client.Channel;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import top.wshape1.shiziapi.common.domain.vo.MessageVo;
import top.wshape1.shiziapi.common.utils.R;
import top.wshape1.shiziapi.message.config.RabbitMqConfig;
import top.wshape1.shiziapi.message.websocket.WsSessionManager;

import java.io.IOException;

/**
 * @author Wshape1
 * @version 1.0
 * @description
 * @since 2023-09-19
 */

@Component
@Slf4j
public class MessageListener {

    @Resource
    private WsSessionManager sessionManager;

    /**
     * 监听私信消息
     */
//    @RabbitListener(bindings = @QueueBinding(
//            value = @Queue(),
//            exchange = @Exchange(value = RabbitMqConfig.SHIZIAPI_MESSAGE_USER_EXCHANGE, type = ExchangeTypes.FANOUT))
//    )
    public ChannelAwareMessageListener listenMessageUserExchange() {
        return (message, channel) -> {
            R<MessageVo> msg = this.getMessageVo(message);
            log.info("listenMessageUserExchange => {}", msg);
            if (msg.isSuccessful()) {
                MessageVo data = msg.getData();
                // 私信消息
                TextMessage textMessage = new TextMessage(JSON.toJSONString(data));
                try {
                    sessionManager.get(data.getUserId().toString()).sendMessage(textMessage);
                } catch (IOException e) {
                    log.error("发送消息给{}失败 error-> {}", data.getUserId(), e.getMessage());
                }

            }
            if (channel != null) {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }
        };
    }

    /**
     * 监听广播消息
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(),
            exchange = @Exchange(value = RabbitMqConfig.SHIZIAPI_MESSAGE_BROADCAST_EXCHANGE, type = ExchangeTypes.FANOUT))
    )
    public void listenMessageBroadcastExchange(Message message, Channel channel, R<MessageVo> msg) throws IOException {
        log.info("listenMessageBroadcastExchange => {}", msg);
        if (msg.isSuccessful()) {
            // 广播消息
            sessionManager.foreach((id, session) -> {
                TextMessage textMessage = new TextMessage(JSON.toJSONString(msg.getData()));
                try {
                    session.sendMessage(textMessage);
                } catch (IOException e) {
                    log.error("发送广播消息给{}失败 error-> {}", id, e.getMessage());
                }
            });

        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

    private R<MessageVo> getMessageVo(Message message) {
        return JSON.parseObject(message.getBody()).to(new TypeReference<>() {
        });
    }
}